home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / util / wb / spriteclock1_1.lha / SpriteClock.c < prev    next >
C/C++ Source or Header  |  1993-01-09  |  14KB  |  580 lines

  1. #include <exec/alerts.h>
  2. #include <workbench/startup.h>
  3. #include <devices/input.h>
  4. #include <intuition/intuitionbase.h>
  5.  
  6. #include <proto/exec.h>
  7. #include <proto/dos.h>
  8. #include <proto/graphics.h>
  9. #include <proto/intuition.h>
  10. #include <proto/timer.h>
  11. #include <proto/icon.h>
  12. #include <proto/commodities.h>
  13.  
  14. #include <MyStartup.h>
  15. #include <MyLib.h>
  16.  
  17. /***********************************************/
  18.  
  19. long Defaults[5]=
  20.    {
  21.       0,0,
  22.       1,
  23.       3,0
  24.    };
  25.  
  26. /***********************************************/
  27.  
  28. #define FONT_HEIGHT    7
  29.  
  30. struct SpriteImage
  31.    {
  32.       ULONG posctl;
  33.       ULONG Data[FONT_HEIGHT+1];
  34.       ULONG reserved;
  35.    };
  36.  
  37. /***********************************************/
  38.  
  39. struct Library *GfxBase;
  40. struct Library *IconBase;
  41. struct Library *CxBase;
  42. struct IntuitionBase *IntuitionBase;
  43. struct Device *TimerBase;
  44.  
  45. CxObj *Broker, *MouseMoveObject, *LeftButtonUpObject;
  46.  
  47. struct SpriteImage chip SpriteImage[2];
  48.  
  49. struct SimpleSprite SimpleSprite=
  50.    {
  51.       (UWORD *)&SpriteImage[1],
  52.       FONT_HEIGHT,
  53.       0,0,
  54.       -1
  55.    };
  56.  
  57. UWORD FontData[FONT_HEIGHT*3]=
  58.    {
  59.       0xE4EE,0xAEEE,0xEE00,
  60.       0xA422,0xA882,0xAA00,
  61.       0xA422,0xA882,0xAA00,
  62.       0xA4EE,0xEEE2,0xEE00,
  63.       0xA482,0x22A2,0xA200,
  64.       0xA482,0x22A2,0xA200,
  65.       0xE4EE,0x2EE2,0xEE00
  66.    };
  67.  
  68. struct EasyStruct EasyStruct=
  69.    {
  70.       sizeof(struct EasyStruct),
  71.       0,
  72.       "SpriteClock V1.1 Installation error",
  73.       NULL,
  74.       "Quit"
  75.    };
  76.  
  77. struct NewBroker NewBroker=
  78.    {
  79.       NB_VERSION,
  80.       "SpriteClock",
  81.       "SpriteClock V1.1 09-Jan-93 C. Stieber",
  82.       "Display a clock in a sprite",
  83.       0,
  84.       0,
  85.       0,
  86.       NULL,
  87.       0
  88.    };
  89.  
  90. char Version[]="$VER: SpriteClock 1.1 (09.01.93)";
  91.  
  92. struct SpriteImage *NewImage=&SpriteImage[0];
  93. struct SpriteImage *OldImage=&SpriteImage[1];
  94.  
  95. struct timerequest timerequest;
  96.  
  97. WORD DeltaX, DeltaY;
  98.  
  99. struct
  100.    {
  101.       long *X;
  102.       long *Y;
  103.       long *SpriteNumber;
  104.       long *DrawingColor;
  105.       long *BackgroundColor;
  106.    } Arguments=
  107.    {
  108.       &Defaults[0],
  109.       &Defaults[1],
  110.       &Defaults[2],
  111.       &Defaults[3],
  112.       &Defaults[4],
  113.    };
  114.  
  115. struct RDArgs *RDArgs;
  116.  
  117. struct SignalSemaphore SpriteSemaphore;
  118.  
  119. WORD MouseX, MouseY;
  120.  
  121. /***********************************************/
  122.  
  123. void CloseAll(void)
  124.  
  125. {
  126.    if (Broker)
  127.       {
  128.          ActivateCxObj(Broker,0);
  129.          DeleteCxObjAll(Broker);
  130.       }
  131.  
  132.    if (SimpleSprite.num!=-1) FreeSprite(SimpleSprite.num);
  133.  
  134.    if (timerequest.tr_node.io_Device)
  135.       {
  136.          AbortIO((struct IORequest *)&timerequest);
  137.          WaitIO((struct IORequest *)&timerequest);
  138.          CloseDevice((struct IORequest *)&timerequest);
  139.       }
  140.  
  141.    ReplyMessages(NewBroker.nb_Port);
  142.  
  143.    if (RDArgs) FreeArgs(RDArgs);
  144.  
  145.    CloseLibrary(CxBase);
  146.    CloseLibrary(GfxBase);
  147.    CloseLibrary(IntuitionBase);
  148. }
  149.  
  150. /***********************************************/
  151.  
  152. void __regargs DrawDigit(UWORD Digit, int BitPos)
  153.  
  154. {
  155.    UWORD i;
  156.    ULONG *FontPointer;
  157.    ULONG FontMask;
  158.    UWORD *DestPointer;
  159.    UWORD DestValue;
  160.  
  161.    Digit=Digit*4;
  162.    if (Digit<16)
  163.       {
  164.          FontMask=0xf0000000>>Digit;
  165.          FontPointer=(ULONG *)FontData;
  166.       }
  167.    else
  168.       {
  169.          FontMask=0xf0000000>>(Digit-=16);
  170.          FontPointer=(ULONG *)(FontData+1);
  171.       }
  172.    DestPointer=(UWORD *)(NewImage->Data);
  173.    for (i=0; i<FONT_HEIGHT; i++)
  174.       {
  175.          DestValue=((*FontPointer & FontMask)<<Digit)>>(BitPos+16);
  176.          if (*Arguments.DrawingColor & 1)
  177.             {
  178.                *DestPointer|=DestValue;
  179.             }
  180.          else
  181.             {
  182.                *DestPointer&=~DestValue;
  183.             }
  184.          DestPointer++;
  185.          if (*Arguments.DrawingColor & 2)
  186.             {
  187.                *DestPointer|=DestValue;
  188.             }
  189.          else
  190.             {
  191.                *DestPointer&=~DestValue;
  192.             }
  193.          DestPointer++;
  194.          FontPointer=(ULONG *)(((UWORD *)FontPointer)+3);
  195.       }
  196. }
  197.  
  198. /***********************************************/
  199.  
  200. void DrawTime(void)
  201.  
  202. {
  203.    UWORD i;
  204.    ULONG *DestPointer;
  205.    ULONG Hour, Minute;
  206.  
  207.    DestPointer=NewImage->Data;
  208.    Hour=(*Arguments.BackgroundColor & 1) ? 0xffff0000 : 0x00000000;
  209.    if (*Arguments.BackgroundColor & 2) Hour|=0x0000ffff;
  210.    for (i=0; i<FONT_HEIGHT; i++)
  211.       {
  212.          *DestPointer++=Hour;
  213.       }
  214.    Minute=timerequest.tr_time.tv_secs/60;
  215.    if (!(Hour=(Minute/60)%12))
  216.       {
  217.          Hour=12;
  218.       }
  219.    timerequest.tr_time.tv_secs=Minute*60+60;
  220.    timerequest.tr_time.tv_micro=0;
  221.    Minute%=60;
  222.    if (Hour>9)
  223.       {
  224.          DrawDigit(Hour/10,-1);
  225.       }
  226.    DrawDigit(Hour%10,2);
  227.    DrawDigit(Minute/10,8);
  228.    DrawDigit(Minute%10,12);
  229.    if (*Arguments.DrawingColor & 1)
  230.       {
  231.          ((UWORD *)(NewImage->Data))[4]|=0x0200;
  232.          ((UWORD *)(NewImage->Data))[10]|=0x0200;
  233.       }
  234.    else
  235.       {
  236.          ((UWORD *)(NewImage->Data))[4]&=~0x0200;
  237.          ((UWORD *)(NewImage->Data))[10]&=~0x0200;
  238.       }
  239.    if (*Arguments.DrawingColor & 2)
  240.       {
  241.          ((UWORD *)(NewImage->Data))[5]|=0x0200;
  242.          ((UWORD *)(NewImage->Data))[11]|=0x0200;
  243.       }
  244.    else
  245.       {
  246.          ((UWORD *)(NewImage->Data))[5]&=~0x0200;
  247.          ((UWORD *)(NewImage->Data))[11]&=~0x0200;
  248.       }
  249. }
  250.  
  251. /***********************************************/
  252.  
  253. void RepositionSprite(void)
  254.  
  255. {
  256.    ObtainSemaphore(&SpriteSemaphore);
  257.    MoveSprite(NULL,&SimpleSprite,*Arguments.X>>1,*Arguments.Y>>1);
  258.    ReleaseSemaphore(&SpriteSemaphore);
  259. }
  260.  
  261. /***********************************************/
  262.  
  263. void ShowNewSprite(void)
  264.  
  265. {
  266.    struct SpriteImage *Temp;
  267.  
  268.    ChangeSprite(NULL,&SimpleSprite,(void *)NewImage);
  269.    RepositionSprite();
  270.    Temp=NewImage;
  271.    NewImage=OldImage;
  272.    OldImage=Temp;
  273. }
  274.  
  275. /***********************************************/
  276.  
  277. BOOL CheckMousePosition(void)
  278.  
  279. {
  280.    DeltaX=MouseX-*Arguments.X;
  281.    DeltaY=MouseY-*Arguments.Y;
  282.    return(DeltaX>=0 && DeltaX<32 && DeltaY>=0 && DeltaY<(SimpleSprite.height<<1));
  283. }
  284.  
  285. /***********************************************/
  286.  
  287. void GetMouse(void)
  288.  
  289. {
  290.    ULONG IntuitionLock;
  291.  
  292.    IntuitionLock=LockIBase(0);
  293.    MouseX=IntuitionBase->MouseX;
  294.    MouseY=IntuitionBase->MouseY;
  295.    UnlockIBase(IntuitionLock);
  296. }
  297.  
  298. /***********************************************/
  299.  
  300. CxMsg * __asm __saveds LeftButtonDown(register __a0 CxMsg *Message)
  301.  
  302. {
  303.    GetMouse();
  304.    if (CheckMousePosition())
  305.       {
  306.          DisposeCxMsg(Message);
  307.          Message=NULL;
  308.          ActivateCxObj(MouseMoveObject,TRUE);
  309.          ActivateCxObj(LeftButtonUpObject,TRUE);
  310.       }
  311.    return(Message);
  312. }
  313.  
  314. /***********************************************/
  315.  
  316. CxMsg * __asm __saveds MouseMove(register __a0 CxMsg *Message)
  317.  
  318. {
  319.    GetMouse();
  320.    *Arguments.X=MouseX-DeltaX;
  321.    *Arguments.Y=MouseY-DeltaY;
  322.    RepositionSprite();
  323.    return(Message);
  324. }
  325.  
  326. /***********************************************/
  327.  
  328. CxMsg * __asm __saveds LeftButtonUp(register __a0 CxMsg *Message)
  329.  
  330. {
  331.    DisposeCxMsg(Message);
  332.    Message=NULL;
  333.    ActivateCxObj(MouseMoveObject,FALSE);
  334.    ActivateCxObj(LeftButtonUpObject,FALSE);
  335.    return(Message);
  336. }
  337.  
  338. /***********************************************/
  339.  
  340. void __regargs SimpleError(char *String)
  341.  
  342. {
  343.    if (CommandLineLength)
  344.       {
  345.          PutStr(String);
  346.          PutStr("\n");
  347.       }
  348.    else
  349.       {
  350.          EasyStruct.es_TextFormat=String;
  351.          EasyRequestArgs(NULL,&EasyStruct,NULL,NULL);
  352.       }
  353.    CloseAll();
  354.    exit(10);
  355. }
  356.  
  357. /***********************************************/
  358.  
  359. void DosError(char *String, char *Filename)
  360.  
  361. {
  362.    long ErrorCode;
  363.    char ErrorBuffer[82];
  364.    APTR Arguments[2];
  365.  
  366.    Arguments[0]=Filename;
  367.    Arguments[1]=ErrorBuffer;
  368.    if (!Fault(ErrorCode=IoErr(),NULL,ErrorBuffer,82))
  369.       {
  370.          sprintf(ErrorBuffer,"DOS-Error #%ld",ErrorCode);
  371.       }
  372.    if (CommandLineLength)
  373.       {
  374.          VPrintf(String,(long *)Arguments);
  375.          PutStr("\n");
  376.       }
  377.    else
  378.       {
  379.          EasyStruct.es_TextFormat=String;
  380.          EasyRequestArgs(NULL,&EasyStruct,NULL,Arguments);
  381.       }
  382.    CloseAll();
  383.    exit(10);
  384. }
  385.  
  386. /***********************************************/
  387.  
  388. void ProcessMessages(void)
  389.  
  390. {
  391.    BOOL Quit;
  392.    CxMsg *Message;
  393.  
  394.    Quit=FALSE;
  395.    while (!Quit)
  396.       {
  397.          WaitPort(NewBroker.nb_Port);
  398.          if (Message=(CxMsg *)GetMsg(NewBroker.nb_Port))
  399.             {
  400.                if ((struct Message *)Message==&timerequest)
  401.                   {
  402.                      GetSysTime(&timerequest.tr_time);
  403.                      ObtainSemaphore(&SpriteSemaphore);
  404.                      DrawTime();
  405.                      ShowNewSprite();
  406.                      ReleaseSemaphore(&SpriteSemaphore);
  407.                      SendIO((struct IORequest *)&timerequest);
  408.                   }
  409.                else
  410.                   {
  411.                      if (CxMsgType(Message)==CXM_COMMAND)
  412.                         {
  413.                            switch(CxMsgID(Message))
  414.                               {
  415.                                  case CXCMD_DISABLE:   ActivateCxObj(Broker,FALSE);
  416.                                                        ActivateCxObj(MouseMoveObject,FALSE);
  417.                                                        ActivateCxObj(LeftButtonUpObject,FALSE);
  418.                                                        break;
  419.                                  case CXCMD_ENABLE:    ActivateCxObj(Broker,TRUE);
  420.                                                        break;
  421.                                  case CXCMD_UNIQUE:
  422.                                  case CXCMD_KILL:      Quit=TRUE;
  423.                                                        break;
  424.                                  default:              break;
  425.                               }
  426.                         }
  427.                      ReplyMsg((struct Message *)Message);
  428.                   }
  429.             }
  430.       }
  431. }
  432.  
  433. /***********************************************/
  434.  
  435. CxObj *AttachHandler(IX *InputXpression, CxMsg (* __asm __saveds Handler(register __a0 CxMsg *)))
  436.  
  437. {
  438.    CxObj *Filter, *Custom;
  439.  
  440.    if (!(Filter=CxFilter(NULL)))
  441.       {
  442.          SimpleError("Unable to create a commodities filter object");
  443.       }
  444.    SetFilterIX(Filter,InputXpression);
  445.    AttachCxObj(Broker,Filter);
  446.    if (!(Custom=CxCustom(Handler,0)))
  447.       {
  448.          SimpleError("Unable to create a commodities custom object");
  449.       }
  450.    AttachCxObj(Filter,Custom);
  451.    return(Filter);
  452. }
  453.  
  454. /***********************************************/
  455.  
  456. void main(void)
  457.  
  458. {
  459.    static IX InputXpression=
  460.       {
  461.          IX_VERSION,
  462.          IECLASS_RAWMOUSE,
  463.          IECODE_LBUTTON,0xffff,
  464.          IEQUALIFIER_LEFTBUTTON,IEQUALIFIER_LEFTBUTTON | IEQUALIFIER_MIDBUTTON | IEQUALIFIER_RBUTTON,
  465.          0
  466.       };
  467.  
  468.    static char CommandTemplate[]="X/N/K,Y/N/K,SPRITE/N/K,DRAWING_COLOR=DC/N/K,BACKGROUND_COLOR=BC/N/K,PRIORITY=PRI/N/K";
  469.  
  470.    static char *MyToolTypes[]=
  471.       {
  472.          "X",
  473.          "Y",
  474.          "SPRITE",
  475.          "DRAWING_COLOR",
  476.          "BACKGROUND_COLOR",
  477.          "PRIORITY"
  478.       };
  479.  
  480.    int i;
  481.    char *String;
  482.    struct DiskObject *DiskObject;
  483.  
  484.    if (!(IntuitionBase=(struct IntuitionBase *)OpenLibrary(&"Unable to open intuition.library"[15],0)))
  485.       {
  486.          if (CommandLineLength)
  487.             {
  488.                PutStr("Unable to open intuition.library");
  489.                PutStr("\n");
  490.             }
  491.          exit(10);
  492.       }
  493.    if (IntuitionBase->LibNode.lib_Version<37)
  494.       {
  495.          DisplayAlert(AT_Recovery,"\x00\x94\x10" "SpriteClock requires Kickstart V37 or later\x00",29);
  496.          CloseLibrary((struct Library *)IntuitionBase);
  497.          exit(10);
  498.       }
  499.  
  500.    if (CommandLineLength)
  501.       {
  502.          if (!(RDArgs=ReadArgs(CommandTemplate,(long *)&Arguments,NULL)))
  503.             {
  504.                DosError("Error processing arguments: %s%s",NULL);
  505.             }
  506.       }
  507.    else
  508.       {
  509.          if (!(IconBase=OpenLibrary(&"Unable to open icon.library"[15],0)))
  510.             {
  511.                SimpleError("Unable to open icon.library");
  512.             }
  513.          if (!(DiskObject=GetDiskObject(Startup.WBenchMsg->sm_ArgList->wa_Name)))
  514.             {
  515.                CloseLibrary(IconBase);
  516.                DosError("Unable to read file %s:\n%s",Startup.WBenchMsg->sm_ArgList->wa_Name);
  517.             }
  518.          for (i=0; i<8; i++)
  519.             {
  520.                if (String=FindToolType(DiskObject->do_ToolTypes,MyToolTypes[i]))
  521.                   {
  522.                      StrToLong(String,&Defaults[i]);
  523.                   }
  524.             }
  525.          FreeDiskObject(DiskObject);
  526.          CloseLibrary(IconBase);
  527.       }
  528.  
  529.    if (!(GfxBase=OpenLibrary(&"Unable to open graphics.library"[15],0)))
  530.       {
  531.          SimpleError("Unable to open graphics.library");
  532.       }
  533.    if (!(CxBase=OpenLibrary("commodities.library",37)))
  534.       {
  535.          SimpleError("Unable to open commodities.library V37");
  536.       }
  537.  
  538.    if (GetSprite(&SimpleSprite,*Arguments.SpriteNumber)==-1)
  539.       {
  540.          SimpleError("Unable to allocate a sprite");
  541.       }
  542.    SpriteImage[0].reserved=SpriteImage[1].reserved=0;
  543.    SpriteImage[0].Data[FONT_HEIGHT+1]=SpriteImage[1].Data[FONT_HEIGHT+1]=0;
  544.  
  545.    InitSemaphore(&SpriteSemaphore);
  546.    NewBroker.nb_Port=&((struct Process *)FindTask(NULL))->pr_MsgPort;
  547.  
  548.    if (!(Broker=CxBroker(&NewBroker,NULL)))
  549.       {
  550.          SimpleError("Unable to create a commodities broker");
  551.       }
  552.  
  553.    AttachHandler(&InputXpression,LeftButtonDown);
  554.  
  555.    InputXpression.ix_Code=IECODE_LBUTTON | IECODE_UP_PREFIX;
  556.    InputXpression.ix_QualMask=0;
  557.    LeftButtonUpObject=AttachHandler(&InputXpression,LeftButtonUp);
  558.  
  559.    InputXpression.ix_Class=IECLASS_RAWMOUSE;
  560.    InputXpression.ix_CodeMask=0;
  561.    MouseMoveObject=AttachHandler(&InputXpression,MouseMove);
  562.  
  563.    ActivateCxObj(LeftButtonUpObject,FALSE);
  564.    ActivateCxObj(MouseMoveObject,FALSE);
  565.    ActivateCxObj(Broker,TRUE);
  566.  
  567.    timerequest.tr_node.io_Message.mn_ReplyPort=NewBroker.nb_Port;
  568.    if (OpenDevice(&"Unable to open timer.device"[15],UNIT_WAITUNTIL,(struct IORequest *)&timerequest,0))
  569.       {
  570.          SimpleError("Unable to open timer.device");
  571.       }
  572.    TimerBase=timerequest.tr_node.io_Device;
  573.    timerequest.tr_node.io_Command=TR_ADDREQUEST;
  574.    SendIO((struct IORequest *)&timerequest);
  575.  
  576.    ProcessMessages();
  577.    
  578.    CloseAll();
  579. }
  580.